
#include "Agent31.h"

Move Agent31::decideMove() {
    return decideMove(game);
}

Move Agent31::decideMove(GameState* gameState) {
    Move ret;
    int handSize;
    CCardStack* handPointer = &hand;
    if (hand.Size() != 3) {
        Query::debugOut(string("Now has hand ") + hand.Initials() + "\n", 1);
        handSize = hand.Size();
    }
    DrawingStrategy* roundDrawingStrategy = drawingStrategy;
    DiscardStrategy* roundDiscardStrategy = discardStrategy;
    // Decide knock
    if (!gameState->isLastRound()) {
        ret.knock = knockingStrategy->decideKnock(handPointer, gameState);
        if (hand.Size() != 3) {
            handSize = hand.Size();
        }
    }
    else {
        roundDrawingStrategy = endDrawingStrategy;
        roundDiscardStrategy = endDiscardStrategy;
    }
    // Check decision
    if (ret.knock) {
        // Knocked, update state
        gameState->knock(order);
    }
    else {
        // Didn't knock, decide draw
        bool pickFromDiscard = drawingStrategy->pickFromDiscard(handPointer, gameState);
        if (hand.Size() != 3) {
            int nop = hand.Size();
        }
        // Apply decision
        if (pickFromDiscard) {
            const CCard pickedCard = gameState->pickUp(order);
            ret.cardPicked.SetIdx(pickedCard.GetIndex());
            this->hand.Push(pickedCard);
        }
        else {
            const CCard drawnCard = gameState->draw(order);
            ret.cardDrawn.SetIdx(drawnCard.GetIndex());
            hand.Push(drawnCard);
        }
        // Decide discard
        int toDiscard = discardStrategy->pickDiscard(handPointer, pickFromDiscard, gameState);
        if (hand.Size() != 4) {
            int nop = hand.Size();
        }
        // Apply decision
        const CCard discardedCard = hand.RemoveCard(toDiscard);
        ret.cardDiscarded.SetIdx(discardedCard.GetIndex());
        gameState->doDiscard(discardedCard, order);
    }
    return ret;
}

void Agent31::opponentMove(int opponent, const Move& move) {
    knockingStrategy->opponentMove(opponent, move);
    drawingStrategy->opponentMove(opponent, move);
    discardStrategy->opponentMove(opponent, move);
    endDrawingStrategy->opponentMove(opponent, move);
    endDiscardStrategy->opponentMove(opponent, move);
}
